package cn.seqdata.rpt.simple.query;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import com.google.common.collect.Table;

import cn.seqdata.rpt.simple.CubeTable;

/**
 * 维度数据查询
 */
public class DimDataQuerier extends AbstractTableQuerier<Object> {
	protected final String sql;
	protected final String keyColName;

	public DimDataQuerier(String sql, String keyColName) {
		super();

		this.sql = sql;
		this.keyColName = keyColName;
	}

	public void query(CubeTable table, String fkey) {
		// 转换为驼峰命名
		String camelKey = CubeTableCallbackHandler.camelCase(fkey);
		// 通过外键找到所有的列
		Map<Integer, Object> cols = table.cells.column(camelKey);
		// 将列值压入set，消除重复
		Set<Object> keys = new HashSet<>(cols.values());
		// 根据事实表的数据获取维度信息(不输出未用的维度)
		Table<Object, String, Object> dimtbl = get(keys);
		table.dims.put(camelKey, dimtbl);
	}

	@Override
	public void query(Table<Object, String, Object> table, Object... args) {
		Set<Object> keys = new HashSet<>();

		for(Object arg : args) {
			if(arg instanceof Iterable) {
				((Iterable<?>) arg).forEach(keys::add);
			} else {
				keys.add(arg);
			}
		}

		query(table, keys);
	}

	/**
	 * 当keys为空时，输出全部维度数据
	 */
	public void query(Table<Object, String, Object> table, Collection<?> keys) {
		Map<String, Object> paramMap = new HashMap<>();

		String sql = this.sql;
		if(!keys.isEmpty()) {
			sql += String.format(" where %s in (:keys)", keyColName);
			paramMap.put("keys", keys);
		}

		CubeTableCallbackHandler<Object> callbackHandler = new CubeTableCallbackHandler<Object>(table) {
			@Override
			protected Object rowKey(ResultSet rs, int rowNum) throws SQLException {
				return rs.getObject(keyColName);
			}
		};

		NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(getDataSource());
		jdbcTemplate.query(sql, paramMap, callbackHandler);
	}
}
